{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "f0188c89",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import numpy as np\n",
    "import random\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "7d1e9422",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([5, 3, 20])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "torch.Size([2, 3, 20])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "rnn = nn.GRU(10, 20, 2)\n",
    "input = torch.randn(5, 3, 10)\n",
    "h0 = torch.randn(2, 3, 20)\n",
    "output, hn = rnn(input, h0)\n",
    "\n",
    "display(output.shape,hn.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5af9778f",
   "metadata": {},
   "outputs": [],
   "source": [
    "a=torch.LongTensor([[5, 6, 7, 8]]) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bc42c412",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([5])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[:,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "119244bc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.86237038, 0.50418702, 0.19979759],\n",
       "       [0.31648935, 0.23468836, 0.55113505]])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a=np.random.rand(2,3)\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "22c03658",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.86237038],\n",
       "       [0.31648935]])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[:,0:1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "44abb519",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([5, 6, 7, 8])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d8afee7e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([0.2588])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "torch.rand(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "bd34f28e",
   "metadata": {},
   "outputs": [],
   "source": [
    "tgt = torch.LongTensor([[5, 6, 7, 8]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "b47ebad5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([5, 6, 7, 8])"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tgt.view(-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "311bb168",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([5, 6, 7, 8])"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tgt[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "716d15c8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([3])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tgt.argmax(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "a8164fa6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(tensor([ 157, 3682, 4439, 1947, 2004, 1320,  248, 4584]),\n",
       "  tensor([2292, 9654, 5555, 9200, 5500, 7800, 1028, 2504])),\n",
       " (tensor([2571,  220, 3549, 4071]), tensor([3378, 4612, 3164, 1178])),\n",
       " (tensor([ 203, 3753,  426]),\n",
       "  tensor([5292, 3855, 3335, 9327, 9203, 3552, 2558])),\n",
       " (tensor([3432, 3828,  207]), tensor([7902, 6176, 9980])),\n",
       " (tensor([2190,  171,  895, 2475, 3661, 4472, 2787]),\n",
       "  tensor([6010, 1928, 7144, 5334, 6316, 6044, 7633])),\n",
       " (tensor([3720,  882, 2054, 4547,  322, 2785]),\n",
       "  tensor([6626, 9356, 8300, 7829, 8173, 8974, 9710])),\n",
       " (tensor([3742, 4073, 1667, 4388, 4464,  520]),\n",
       "  tensor([3232,  411, 4568, 5469])),\n",
       " (tensor([2583,  785, 4243, 4486, 3150, 3223, 2680]),\n",
       "  tensor([7632, 8964, 9406, 5045, 5980, 6032])),\n",
       " (tensor([1854, 3247, 4132, 3644]),\n",
       "  tensor([ 465, 7576, 9605, 5589, 3032, 4373])),\n",
       " (tensor([ 450, 1688, 3501, 2722, 3604, 3846, 4266,  654]),\n",
       "  tensor([7082, 5350, 6908, 3569, 3218, 2518, 4912, 8625]))]"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 随机生成数据\n",
    "def generate_random_samples(num_samples, src_vocab_size, tgt_vocab_size):\n",
    "    samples = []\n",
    "    for _ in range(num_samples):\n",
    "        src_len = random.randint(3, 8)\n",
    "        tgt_len = random.randint(3, 8)\n",
    "        src = torch.randint(1, src_vocab_size, (src_len,))\n",
    "        tgt = torch.randint(1, tgt_vocab_size, (tgt_len,))\n",
    "        samples.append((src, tgt))\n",
    "    return samples\n",
    "\n",
    "\n",
    "s = generate_random_samples(10,5000,10000)\n",
    "s\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "55bb7576",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "aefce3cd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[1, 0, 8, 6],\n",
       "        [8, 9, 7, 3],\n",
       "        [3, 5, 9, 2]],\n",
       "\n",
       "       [[8, 6, 2, 1],\n",
       "        [7, 9, 8, 2],\n",
       "        [5, 8, 1, 4]]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a=np.random.randint(0, 10, (2, 3,4))\n",
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "9f435129",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 1, 0],\n",
       "       [0, 4, 2]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a2 = np.random.randint(0, 10, (2, 3))\n",
    "a2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "e531c9a0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 0])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a2[:,0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "655f912b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "aaa62ccf",
   "metadata": {},
   "outputs": [],
   "source": [
    "a[:,0] = [[1,1,1,1],[2,2,2,2]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "id": "ed5acc23",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[1, 1, 1, 1],\n",
       "        [4, 9, 3, 5],\n",
       "        [5, 8, 8, 1]],\n",
       "\n",
       "       [[2, 2, 2, 2],\n",
       "        [9, 3, 4, 8],\n",
       "        [8, 2, 5, 2]]])"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "f53ea227",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2, 3, 4)"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "a8ac869a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[1, 4, 5],\n",
       "        [1, 9, 8],\n",
       "        [1, 3, 8],\n",
       "        [1, 5, 1]],\n",
       "\n",
       "       [[2, 9, 8],\n",
       "        [2, 3, 2],\n",
       "        [2, 4, 5],\n",
       "        [2, 8, 2]]])"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a.transpose(0,2,1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "942eaf42",
   "metadata": {},
   "outputs": [],
   "source": [
    "ll = nn.Linear(50, 100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f5a3c58c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "50"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ll.in_features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9267c852",
   "metadata": {},
   "outputs": [],
   "source": [
    "criterion = nn.CrossEntropyLoss()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "76f7b358",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0.1839, -0.4481,  1.1978, -0.1690],\n",
       "        [-0.6227, -0.3377, -1.5120,  0.7315]])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "tensor([1, 3])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "tensor(1.3873)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "a = torch.randn(2,  4)\n",
    "b = torch.randint(0,4,size=(2,)).long()\n",
    "r = criterion(a, b)\n",
    "\n",
    "display(a,b,r)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "b28aa4c0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([-2,  0,  1,  0])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "282ad073",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0.9141,  1.1585, -0.0698,  1.4423],\n",
       "        [-0.7392,  0.4929,  1.6434, -1.4310]])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "id": "03e085ce",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 0.0254,  0.7238, -1.0872, -0.5636],\n",
       "        [-0.0497, -0.3514, -0.7767,  0.0324],\n",
       "        [-0.6762, -1.0043, -0.1106,  0.1977],\n",
       "        [-0.2040,  0.4126, -0.1671, -1.0821],\n",
       "        [-1.2260, -0.5680,  1.1144,  1.7955],\n",
       "        [ 0.4021, -0.5376,  0.9460,  1.0304]])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "tensor([3, 2, 3, 2, 3, 3])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "tensor(1.2785)"
      ]
     },
     "execution_count": 96,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "criterion = nn.CrossEntropyLoss()\n",
    "a = torch.randn(2, 3, 4)\n",
    "b = torch.randint(2,4,size=(2,3)).long()\n",
    "\n",
    "a=a.view(-1, 4)\n",
    "b=b.view(-1)\n",
    "\n",
    "display(a,b)\n",
    "r = criterion(a, b)\n",
    "r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "id": "75902482",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[ 0.7006,  1.7413, -0.7116],\n",
       "         [-1.0255, -1.5477,  2.1549],\n",
       "         [ 0.4762,  0.0815,  1.9374],\n",
       "         [-0.0998, -0.5684,  0.5899]],\n",
       "\n",
       "        [[-1.2330, -0.7726,  1.9677],\n",
       "         [-1.1036, -0.4370,  1.9344],\n",
       "         [-0.5800, -0.8174, -1.9131],\n",
       "         [ 1.0644,  1.4039,  2.3610]]])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "criterion = nn.CrossEntropyLoss()\n",
    "a = torch.randn(2, 3, 4)  # (batch, seq_len, num_classes)\n",
    "b = torch.randint(0, 4, size=(2, 3)).long()  # 注意类别索引范围是[0,3]\n",
    "\n",
    "# 需要将num_classes维度放到第二位\n",
    "a_permuted = a.permute(0, 2, 1)  # (2, 4, 3)\n",
    "loss = criterion(a_permuted, b)\n",
    "display(a_permuted)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "id": "858d9ff5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([2, 3])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "torch.Size([2, 2])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "tensor([[1., 2., 0.],\n",
       "        [1., 2., 3.]])"
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 特征维度必须一样才行\n",
    "x=torch.randn(2, 2, 4)\n",
    "x2 = torch.Tensor([[1, 2], [3, 4]])\n",
    "x3 = torch.Tensor([[2,1,0], [1,4,1]])\n",
    "display(x3.shape,x2.shape)\n",
    "\n",
    "nn.utils.rnn.pad_sequence([torch.Tensor([1,2]),torch.Tensor([1,2,3])],batch_first=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "id": "61278a96",
   "metadata": {},
   "outputs": [
    {
     "ename": "RuntimeError",
     "evalue": "The size of tensor a (2) must match the size of tensor b (3) at non-singleton dimension 1",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mRuntimeError\u001b[0m                              Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[120], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mnn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mutils\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrnn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpad_sequence\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[43mx2\u001b[49m\u001b[43m,\u001b[49m\u001b[43mx3\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43mbatch_first\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n",
      "File \u001b[1;32md:\\VirtualProject\\Python37Env\\torch_py38\\lib\\site-packages\\torch\\nn\\utils\\rnn.py:400\u001b[0m, in \u001b[0;36mpad_sequence\u001b[1;34m(sequences, batch_first, padding_value)\u001b[0m\n\u001b[0;32m    396\u001b[0m         sequences \u001b[38;5;241m=\u001b[39m sequences\u001b[38;5;241m.\u001b[39munbind(\u001b[38;5;241m0\u001b[39m)\n\u001b[0;32m    398\u001b[0m \u001b[38;5;66;03m# assuming trailing dimensions and type of all the Tensors\u001b[39;00m\n\u001b[0;32m    399\u001b[0m \u001b[38;5;66;03m# in sequences are same and fetching those from sequences[0]\u001b[39;00m\n\u001b[1;32m--> 400\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mtorch\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_C\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_nn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpad_sequence\u001b[49m\u001b[43m(\u001b[49m\u001b[43msequences\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbatch_first\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpadding_value\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[1;31mRuntimeError\u001b[0m: The size of tensor a (2) must match the size of tensor b (3) at non-singleton dimension 1"
     ]
    }
   ],
   "source": [
    "nn.utils.rnn.pad_sequence([x2,x3],batch_first=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "id": "f3496c05",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(tensor([ 284,   77, 4950, 1967, 1288, 1666, 2483, 1015]), tensor([ 793, 6205, 4695, 7611, 1515,  724])), (tensor([ 819, 2961, 2194, 3728, 2814, 3022, 3035, 2664]), tensor([7135, 1446,  705, 6556, 2722, 2399, 9741])), (tensor([2244, 4387,  317, 4658,  362, 1816]), tensor([4037, 9527, 5037, 2999, 4621, 9938, 8944, 3911]))]\n",
      "[(tensor([ 284,   77, 4950, 1967, 1288, 1666, 2483, 1015]), tensor([ 793, 6205, 4695, 7611, 1515,  724])), (tensor([ 819, 2961, 2194, 3728, 2814, 3022, 3035, 2664]), tensor([7135, 1446,  705, 6556, 2722, 2399, 9741])), (tensor([2244, 4387,  317, 4658,  362, 1816]), tensor([4037, 9527, 5037, 2999, 4621, 9938, 8944, 3911]))]\n"
     ]
    }
   ],
   "source": [
    "\n",
    "def generate_random_samples(num_samples, src_vocab_size, tgt_vocab_size):\n",
    "    samples = []\n",
    "    for _ in range(num_samples):\n",
    "        src_len = random.randint(3, 8)\n",
    "        tgt_len = random.randint(3, 8)\n",
    "        src = torch.randint(1, src_vocab_size, (src_len,))\n",
    "        tgt = torch.randint(1, tgt_vocab_size, (tgt_len,))\n",
    "        samples.append((src, tgt))\n",
    "    return samples\n",
    "\n",
    "\n",
    "s = generate_random_samples(10,5000,10000)\n",
    "\n",
    "def change(batch):\n",
    "    print(batch)\n",
    "    return batch\n",
    "\n",
    "DataLoader = torch.utils.data.DataLoader(s, batch_size=3, shuffle=True,collate_fn=change)  # batch_size=2\n",
    "\n",
    "\n",
    "for x in DataLoader:\n",
    "    print(x)\n",
    "    break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "id": "da02861f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PackedSequence(data=tensor([0.3325, 1.0710]), batch_sizes=tensor([2]), sorted_indices=tensor([0, 1]), unsorted_indices=tensor([0, 1]))\n"
     ]
    }
   ],
   "source": [
    "x= torch.randn(2, 3)\n",
    "# display(x)\n",
    "packed  = nn.utils.rnn.pack_padded_sequence(\n",
    "            x, torch.Tensor([1,1]), batch_first=True, enforce_sorted=False\n",
    "        )\n",
    "print(packed)\n",
    "# print(packed[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "id": "b4ef0246",
   "metadata": {},
   "outputs": [
    {
     "ename": "RuntimeError",
     "evalue": "`lengths` array must be sorted in decreasing order when `enforce_sorted` is True. You can pass `enforce_sorted=False` to pack_padded_sequence and/or pack_sequence to sidestep this requirement if you do not need ONNX exportability.",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mRuntimeError\u001b[0m                              Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[137], line 6\u001b[0m\n\u001b[0;32m      3\u001b[0m lengths \u001b[38;5;241m=\u001b[39m torch\u001b[38;5;241m.\u001b[39mtensor([\u001b[38;5;241m3\u001b[39m, \u001b[38;5;241m2\u001b[39m, \u001b[38;5;241m4\u001b[39m])\n\u001b[0;32m      5\u001b[0m \u001b[38;5;66;03m# 2. 打包并送入RNN\u001b[39;00m\n\u001b[1;32m----> 6\u001b[0m packed \u001b[38;5;241m=\u001b[39m \u001b[43mnn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mutils\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrnn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpack_padded_sequence\u001b[49m\u001b[43m(\u001b[49m\u001b[43msrc\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlengths\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbatch_first\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[0;32m      7\u001b[0m packed\n",
      "File \u001b[1;32md:\\VirtualProject\\Python37Env\\torch_py38\\lib\\site-packages\\torch\\nn\\utils\\rnn.py:264\u001b[0m, in \u001b[0;36mpack_padded_sequence\u001b[1;34m(input, lengths, batch_first, enforce_sorted)\u001b[0m\n\u001b[0;32m    260\u001b[0m     batch_dim \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m batch_first \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m    261\u001b[0m     \u001b[38;5;28minput\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28minput\u001b[39m\u001b[38;5;241m.\u001b[39mindex_select(batch_dim, sorted_indices)\n\u001b[0;32m    263\u001b[0m data, batch_sizes \u001b[38;5;241m=\u001b[39m \\\n\u001b[1;32m--> 264\u001b[0m     \u001b[43m_VF\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_pack_padded_sequence\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43minput\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlengths\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbatch_first\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m    265\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m _packed_sequence_init(data, batch_sizes, sorted_indices, \u001b[38;5;28;01mNone\u001b[39;00m)\n",
      "\u001b[1;31mRuntimeError\u001b[0m: `lengths` array must be sorted in decreasing order when `enforce_sorted` is True. You can pass `enforce_sorted=False` to pack_padded_sequence and/or pack_sequence to sidestep this requirement if you do not need ONNX exportability."
     ]
    }
   ],
   "source": [
    "# 1. 准备数据\n",
    "src = torch.tensor([[1,2,3,0], [4,5,0,0], [6,7,8,9]])  # batch_first=True\n",
    "lengths = torch.tensor([3, 2, 4])\n",
    "\n",
    "# 2. 打包并送入RNN\n",
    "packed = nn.utils.rnn.pack_padded_sequence(src, lengths, batch_first=True)\n",
    "packed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e17a8b63",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "torch_py38",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.7rc1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
